package com.rutas.java;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Locale;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.json.JSONException;
import org.json.JSONObject;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.androidplot.series.XYSeries;
import com.androidplot.xy.BoundaryMode;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYPlot;
import com.markupartist.android.widget.ActionBar;
import com.markupartist.android.widget.ActionBar.AbstractAction;

public class info extends Activity {
	
	private XYPlot grafica;
	private ActionBar actionBar;

	private Handler handlerGraf;
	private Handler handlerWeather;
	private String miXML;
	private TextView tvNombre;
	private double valor;
	private double lat = 0;
	private double lon = 0;
	private RelativeLayout rlInfo, rlDescription;
	private LinearLayout llWeather;
	
//-----------Funciones-----------------------------------------	
	private boolean isInAssets (String cadena){
		return !cadena.startsWith("!");
	}
	
	private String getStringResourceByName(String aString){
	  String packageName = getPackageName();
	  int resId = this.getResources().getIdentifier(aString, "string", packageName);
	  return getString(resId);
	}
	private int getDrawableResourceByName(String aString){
		  String packageName = getPackageName();
		  int drawableResourceId = this.getResources().getIdentifier(aString, "drawable", packageName);
		  return drawableResourceId;
		}
	
	private Drawable rotateIcon(float grados, Bitmap flechaBitmap){
			
			Matrix matrix = new Matrix();
			matrix.postRotate(grados, flechaBitmap.getWidth(), flechaBitmap.getHeight());
			Bitmap rotatedBitmap = Bitmap.createBitmap(flechaBitmap, 0, 0, flechaBitmap.getWidth(), flechaBitmap.getHeight(), matrix, true);
			return new BitmapDrawable(getResources(),rotatedBitmap);
		}

	public class ExampleAction extends AbstractAction {
		private int icon;
		public ExampleAction(int arg0) {
			super(arg0);
			icon = arg0;
		}
        @Override
        public void performAction(View view) {
        	switch (icon){
        	case android.R.drawable.ic_menu_mapmode:	//mapa
        		Intent miIntent = new Intent(); 
				miIntent.putExtra("sendero", tvNombre.getText());
				setResult(Activity.RESULT_CANCELED, miIntent);
				finish();
				break;
        	case android.R.drawable.ic_menu_gallery:	//plot
				rlInfo.setVisibility(View.GONE);
				rlDescription.setVisibility(View.GONE);
				llWeather.setVisibility(View.GONE);
				grafica.setVisibility(View.VISIBLE);
        		break;
        	case android.R.drawable.ic_menu_info_details:  //info
				grafica.setVisibility(View.GONE);
				rlInfo.setVisibility(View.VISIBLE);
				llWeather.setVisibility(View.GONE);
				rlDescription.setVisibility(View.VISIBLE);
        		break;
        	case R.drawable.ic_info_weather:	//weather
				grafica.setVisibility(View.GONE);
				rlDescription.setVisibility(View.GONE);					
				rlInfo.setVisibility(View.VISIBLE);
				llWeather.setVisibility(View.VISIBLE);
        		break;
        	default:
        		setResult(Activity.RESULT_OK);
            	finish();
            	break;
        	}
        }
    }
//------------------------------------------------------------------	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.info);

		tvNombre = (TextView) findViewById(R.id.TextViewNombre);
		EditText etDurac = (EditText)findViewById(R.id.EditTextDurac);
		EditText etLong = (EditText)findViewById(R.id.EditTextLong);
		EditText etDific = (EditText)findViewById(R.id.EditTextDific);
		EditText etDescrip = (EditText)findViewById(R.id.EditTextDescrip);

		rlInfo = (RelativeLayout)findViewById(R.id.rlInfo);
		llWeather = (LinearLayout) findViewById(R.id.llWeather);
		rlDescription = (RelativeLayout)findViewById(R.id.rlDescription);

		//Actionbar
		actionBar = (ActionBar)findViewById(R.id.actionbar);
        actionBar.setHomeAction(new ExampleAction(android.R.drawable.ic_menu_revert));       
        actionBar.setProgressBarVisibility(View.VISIBLE);
        actionBar.setTitle("");
		
		grafica = (XYPlot)this.findViewById(R.id.Grafica);
		//Manejador del hilo que lee la altura de un KML
		handlerGraf = new Handler(){
			@Override
			public void handleMessage(Message msg){
				if (msg.obj != null){
					final ArrayList<Integer> serieY = (ArrayList<Integer>) msg.obj;
			        //Number[] series1Numbers = {1, 8, 5, 2, 7, 4, 10, 3, 4, 5, 5, 8, 1, 4, 1, 5, 10, 11, 6};
			       /*  XYSeries series1 = new SimpleXYSeries(Arrays.asList(series1Numbers), 
			         		SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Desnivel");*/
					valor = valor / (double)serieY.size();
					ArrayList<Double> serieX = new ArrayList<Double>();
					double sum = 0;
					int tam = serieY.size();
					double max = 0;
					double min = 3900;
					for (int i = 0; i < tam;i++){
						double var = serieY.get(i);
						if (var > max){
							max = var;
						}
						if (var < min){
							min = var;
						}
						serieX.add(sum);
						sum += valor;
					}
					double upperRangeBoundary = 1500;
					double lowRangeBoundary = 500;
					if (max > upperRangeBoundary){
						upperRangeBoundary = max + 400;
					}
					if (min < lowRangeBoundary){
						lowRangeBoundary = 0;
					}
						
			        XYSeries serie = new SimpleXYSeries(serieX, serieY, getApplicationContext().getString(R.string.desnivel));
			         
			         LineAndPointFormatter series1Format = new LineAndPointFormatter(
			                 Color.rgb(0, 200, 0),                   // line color
			                 Color.rgb(0, 100, 0),                   // point color
			                 Color.argb(150, 150, 190, 150));
			         
			         grafica.addSeries(serie, series1Format);
			         grafica.setRangeBoundaries(lowRangeBoundary, upperRangeBoundary, BoundaryMode.FIXED);
			         grafica.setTicksPerRangeLabel(1);
			         grafica.setTicksPerDomainLabel(3);
			         grafica.disableAllMarkup();
			         grafica.setRangeLabel(getApplicationContext().getString(R.string.altitud));
			         grafica.setDomainLabel(getApplicationContext().getString(R.string.distancia));

			         int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6, getResources().getDisplayMetrics());
			 	     grafica.getGraphWidget().setMarginBottom(px);
			 	     grafica.getGraphWidget().setMarginLeft(px);
			 	     grafica.getGraphWidget().getGridBackgroundPaint().setColor(Color.WHITE);
			 	     grafica.getGraphWidget().getBackgroundPaint().setColor(Color.TRANSPARENT);
			 	     grafica.getGraphWidget().getDomainOriginLinePaint().setColor(Color.BLACK);
					 grafica.getGraphWidget().getRangeOriginLinePaint().setColor(Color.BLACK);
					 grafica.getGraphWidget().getDomainOriginLabelPaint().setColor(Color.WHITE);
			 	     grafica.getBackgroundPaint().setColor(Color.TRANSPARENT);
			 	     grafica.getBorderPaint().setColor(getResources().getColor(R.color.lightGreen));
			 	     grafica.getTitleWidget().getLabelPaint().setColor(Color.WHITE);	    
				     grafica.getLegendWidget().getTextPaint().setColor(Color.WHITE);				   
					 grafica.getRangeLabelWidget().getLabelPaint().setColor(Color.WHITE);
					 
					 actionBar.addAction(new ExampleAction(android.R.drawable.ic_menu_gallery));
				}
			}
		};
		
		Bundle datos = getIntent().getExtras();	
		String[] informacion = datos.getStringArray("informacion");
		String activityName = datos.getString("ActivityName");
		
		if (activityName.equals("Tab2")){	//Si viene de tab2 muestra el boton
			actionBar.addAction(new ExampleAction(android.R.drawable.ic_menu_mapmode));	//ic_menu_mapmode
		}
		actionBar.addAction(new ExampleAction(android.R.drawable.ic_menu_info_details));
		//Sacamos los datos del bundle y los pasamos a los editText
		//nombre, descripcion, duracion, longitud, dificultad, kml, lat y lon
		if (datos != null){
			tvNombre.setText(informacion[0]);
			etDescrip.setText(informacion[1]);
			String[] tiempo = informacion[2].split("\\.");
			String cadena = tiempo[0] + getApplicationContext().getString(R.string.horas);
			if (tiempo.length == 2)
				cadena = tiempo[0] + " h " + tiempo[1] + " min";
			etDurac.setText(cadena);
			etLong.setText(informacion[3] + " Km");
			int dific = Integer.parseInt(informacion[4]);
			String[] opt = this.getResources().getStringArray(R.array.opcionDific);
			etDific.setText(opt[dific]);
			miXML = informacion[5];
			valor = Double.parseDouble(informacion[3]);
			double valueLat = Double.parseDouble(informacion[6]);
			double valueLon = Double.parseDouble(informacion[7]);
			lat = datos.getDouble("lat",valueLat);	//obtenemos coordenadas
			lon = datos.getDouble("lon",valueLon);
		}
		
		if (!miXML.contentEquals("")){
		Thread myThread = new Thread(new Runnable(){
			public void run(){
				SAXParserFactory spf = SAXParserFactory.newInstance(); 
		        try {
					SAXParser sp = spf.newSAXParser();
					XMLReader xr = sp.getXMLReader();
					Message mensaje = new Message();
					
					InputStream myInput;
			        if (!isInAssets(miXML)){
			        	//File f = new File(Environment.getExternalStorageDirectory()+"/rutas/"+ xmlPath);
			        	File f = new File("/data/data/com.rutas.java/files/", miXML);
			        	myInput = new FileInputStream(f);
			        }
			        else
			        	myInput = getBaseContext().getAssets().open(miXML);
			        
					InputSource archivo = new InputSource(myInput);
					archivo.setEncoding("UTF-8");
					
					String filenameArray[] = miXML.split("\\.");
			        String extension = filenameArray[filenameArray.length-1];
					
			        if (extension.toLowerCase().contentEquals("kml")){
						KmlHandler kml = new KmlHandler();
						xr.setContentHandler(kml);	
						xr.parse(archivo);
						mensaje.obj = kml.getAltitud();
			        }else{
			        	GpxHandler gpx = new GpxHandler(false);
			        	xr.setContentHandler(gpx);
						xr.parse(archivo);
						mensaje.obj = gpx.getAltitud();
			        }
					handlerGraf.sendMessage(mensaje);
					myInput.close();
		        } catch (ParserConfigurationException e) {
					Log.d("Superposicion/OnTap/Parser ", e.toString());
					e.printStackTrace();
				} catch (SAXException e) {
					Log.d("Superposicion/OnTap/SAX ", e.toString());
					e.printStackTrace();
				} catch (IOException e) {
					Log.d("Superposicion/OnTap/InputStream ", e.toString());
					e.printStackTrace();
			}
		}});
		myThread.start();
		}
		
		handlerWeather = new Handler(){
			@Override
			public void handleMessage(Message msg){
				String mensaje = (String) msg.obj;
				try {
					JSONObject jObject = new JSONObject(mensaje);
					JSONObject currentCond = jObject.getJSONObject("data").getJSONArray("current_condition").getJSONObject(0);
					String value = currentCond.getString("weatherCode");
					TextView tvWeatherDesc = (TextView) findViewById(R.id.tvWeatherDesc);
					tvWeatherDesc.setText(getStringResourceByName("w"+value));

					Bitmap flechaBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.wind_direc);
					
					ImageView iconWeather = (ImageView) findViewById(R.id.iconWeather);
					iconWeather.setImageResource(getDrawableResourceByName("i"+value)); 
					TextView tvCloudCover = (TextView) findViewById(R.id.tvCloudCover);
					tvCloudCover.setText(getResources().getString(R.string.nubosidad)+currentCond.getString("cloudcover")+ "%");
					TextView tvHumidity = (TextView) findViewById(R.id.tvHumidity);
					tvHumidity.setText(" "+getResources().getString(R.string.humedad)+currentCond.getString("humidity")+"%");
					TextView tvPrecip = (TextView) findViewById(R.id.tvPrecip);
					tvPrecip.setText(" "+getResources().getString(R.string.precip)+currentCond.getString("precipMM")+" Lm2");
					TextView tvPressure = (TextView) findViewById(R.id.tvPressure);
					tvPressure.setText(" "+getResources().getString(R.string.presion)+currentCond.getString("pressure")+" mb");
					TextView tvTemp = (TextView) findViewById(R.id.tvTemperatura);
					String paramTemp = currentCond.getString("temp_C") + " ºC";
					if (Locale.getDefault() == Locale.US)
						paramTemp = currentCond.getString("temp_F")+" ºF";
					tvTemp.setText(paramTemp);
					
					TextView tvWindDir = (TextView) findViewById(R.id.tvWindDirec);
					tvWindDir.setText(currentCond.getString("winddir16Point") + " |");
					Drawable d1 = rotateIcon(currentCond.getInt("winddirDegree"), flechaBitmap);
					//d1.setBounds(0, 0, d1.getIntrinsicWidth(), d1.getIntrinsicHeight());
					ImageView imgVWinDir = (ImageView)findViewById(R.id.iconWindDir);
					imgVWinDir.setImageDrawable(d1);					
					//tvWindDir.setCompoundDrawables(d1, null, null, null);
					TextView tvWindVel = (TextView) findViewById(R.id.tvWindVeloc);
					String cadena = currentCond.getString("windspeedKmph")+ " km/h";
					if ((Locale.getDefault() == Locale.UK) || (Locale.getDefault() == Locale.US))
						cadena = currentCond.getString("windspeedMiles") + " miles/h";
					tvWindVel.setText(cadena);	
					//Prevision
					JSONObject prev = jObject.getJSONObject("data").getJSONArray("weather").getJSONObject(0);
					JSONObject prevHourly = prev.getJSONArray("hourly").getJSONObject(0);
					String value2 = prevHourly.getString("weatherCode");
					ImageView iconWeather2 = (ImageView) findViewById(R.id.iconWeather2);
					iconWeather2.setImageResource(getDrawableResourceByName("i"+value2));
					TextView tvPrecip2 = (TextView) findViewById(R.id.tvPrecip2);
					tvPrecip2.setText(getResources().getString(R.string.precip)+prevHourly.getString("precipMM")+" Lm2");					
					TextView tvTemp2 = (TextView) findViewById(R.id.tvTemperatura2);
					
					
					String paramTemp2 = prev.getString("maxtempC") + " ºC - "+prev.getString("mintempC")+" ºC";
					if (Locale.getDefault() == Locale.US)
						paramTemp2 = prev.getString("maxtempF")+ " ºF - "+prev.getString("mintempF")+" ºF";
					tvTemp2.setText(paramTemp2);
					
					TextView tvWeatherDesc2 = (TextView) findViewById(R.id.tvWeatherDesc2);
					tvWeatherDesc2.setText(getStringResourceByName("w"+value2));
					TextView tvWindDir2 = (TextView) findViewById(R.id.tvWindDirec2);
					tvWindDir2.setText(prevHourly.getString("winddir16Point")+ " |");
					Drawable d2 = rotateIcon(prevHourly.getInt("winddirDegree"), flechaBitmap);					
					//d2.setBounds(0, 0, d2.getIntrinsicWidth(), d2.getIntrinsicHeight());
					//tvWindDir2.setCompoundDrawables(d2, null, null, null);
					ImageView imgVWinDir2 = (ImageView)findViewById(R.id.iconWindDir2);
					imgVWinDir2.setImageDrawable(d2);
					TextView tvWindVel2 = (TextView) findViewById(R.id.tvWindVeloc2);
					String cadena2 = prevHourly.getString("windspeedKmph")+ " km/h";
					if ((Locale.getDefault() == Locale.UK) || (Locale.getDefault() == Locale.US))
						cadena2 = prevHourly.getString("windspeedMiles") + " miles/h";
					tvWindVel2.setText(cadena2);	
					actionBar.setProgressBarVisibility(View.GONE);
					
					actionBar.addAction(new ExampleAction(R.drawable.ic_info_weather));
				} catch (JSONException e) {
					e.printStackTrace();
					actionBar.setProgressBarVisibility(View.GONE);
					//Log.e("Error!", e.toString());
				}
			}			
		};

	       Thread weatherThread = new Thread(){
	        	@Override
	        	public void run(){
	        		
	    			RutasGlobal rg = ((RutasGlobal) getApplicationContext());	//Manipulamos la cache global 
	    			rg.initialize();
	    			long key = (long)(lat*1E6) + (long)(lon*1E6);
	    			String result = rg.searchElement(key);
	        		if (result == null){	//Si result no esta en cache...
		        		DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
		        		String uri ="http://api.worldweatheronline.com/free/v2/weather.ashx?q="+ lat +","+ lon +"&format=json&num_of_days=1&tp=24&key=4dd5f7defe860cc6cb67909a84684a3f50bc160d";		        			
		        		//String uri = "http://free.worldweatheronline.com/feed/weather.ashx?q="+ lat +","+ lon +"&format=json&num_of_days=1&key=da8292f4dd111341131401";
		        		HttpPost httppost = new HttpPost(uri);
		        		httppost.setHeader("Content-type", "application/json");
		        		try {
							HttpResponse response = httpclient.execute(httppost);
							HttpEntity entity = response.getEntity();
							InputStream inputStream = entity.getContent();
							
							BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
							result = reader.readLine();
							inputStream.close();
							if (result != null){
								Log.v("Dentro de thread", "Correcto!");
								rg.addElement(key, result);	//cacheamos json
								Message msg = new Message();
								msg.obj = result;
								//Log.v("Thread weather", "Info NO cacheada!!");
								handlerWeather.sendMessage(msg);
							}else
								actionBar.setProgressBarVisibility(View.GONE);
						} catch (ClientProtocolException e) {
							actionBar.setProgressBarVisibility(View.GONE);
							e.printStackTrace();
						} catch (IOException e) {	
							actionBar.setProgressBarVisibility(View.GONE);
							e.printStackTrace();
						}					
	        		}else{	//Si result existe en cache...
	        			Message msg = new Message();
						msg.obj = result;
						//Log.v("Thread weather", "Info cacheada!!");
	        			handlerWeather.sendMessage(msg);
	        		}
	        	}
	        };
	        weatherThread.start();
	}
	@Override
	public void onBackPressed() {
		setResult(Activity.RESULT_OK);
		finish();
	}
}